/***************************************************************************
 *   Copyright (C) 2010 by programmeboy                                    *
 *   programmeboy@gmail.com                                                *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.                                        *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             * 
 ***************************************************************************/

#ifndef __PORT_H__
#define __PORT_H__

#include <ntddk.h>
#include "cpu.h"

#define KEYB_REGISTER_STATUS  0x64
#define KEYB_REGISTER_COMMAND 0x64
#define KEYB_REGISTER_OUTPUT  0x60
#define KEYB_REGISTER_DATA    0x60

#define KEYB_STATUS_OBUFFER_FULL        (1 << 0)
#define KEYB_STATUS_IBUFFER_FULL        (1 << 1)
#define KEYB_STATUS_TRANSMIT_TIMEOUT    (1 << 5)
#define KEYB_STATUS_PARITY_ERROR        (1 << 7)
#define POLL_STATUS_ITERATIONS 12000

#define KEYB_COMMAND_WRITE_OUTPUT      0xd2
#define KEYB_COMMAND_DISABLE_KEYBOARD  0xad
#define KEYB_COMMAND_ENABLE_KEYBOARD   0xae
#define KEYB_COMMAND_DISABLE_MOUSE     0xa7
#define KEYB_COMMAND_ENABLE_MOUSE      0xa8

#define IS_SCANCODE_RELEASE(c) (c & 0x80)
#define SCANCODE_RELEASE_FLAG  0x80

#define SCANCODE_KEYPAD0	82
#define SCANCODE_KEYPAD1	79
#define SCANCODE_KEYPAD2	80
#define SCANCODE_KEYPAD3	81
#define SCANCODE_KEYPAD4	75
#define SCANCODE_KEYPAD5	76
#define SCANCODE_KEYPAD6	77
#define SCANCODE_KEYPAD7	71
#define SCANCODE_KEYPAD8	72
#define SCANCODE_KEYPAD9	73
#define SCANCODE_KEYPADENTER	96
#define SCANCODE_KEYPADPLUS	78
#define SCANCODE_KEYPADMINUS	74

#define SCANCODE_Q		16
#define SCANCODE_W		17
#define SCANCODE_E		18
#define SCANCODE_R		19
#define SCANCODE_T		20
#define SCANCODE_Y		21
#define SCANCODE_U		22
#define SCANCODE_I		23
#define SCANCODE_O		24
#define SCANCODE_P		25
#define SCANCODE_A		30
#define SCANCODE_S		31
#define SCANCODE_D		32
#define SCANCODE_F		33
#define SCANCODE_G		34
#define SCANCODE_H		35
#define SCANCODE_J		36
#define SCANCODE_K		37
#define SCANCODE_L		38
#define SCANCODE_Z		44
#define SCANCODE_X		45
#define SCANCODE_C		46
#define SCANCODE_V		47
#define SCANCODE_B		48
#define SCANCODE_N		49
#define SCANCODE_M		50

#define SCANCODE_FSLASH         53
#define SCANCODE_BSLASH         43

#define SCANCODE_ESCAPE		1
#define SCANCODE_ENTER		28
#define SCANCODE_RIGHTCONTROL	97
#define SCANCODE_CONTROL	97
#define SCANCODE_RIGHTALT	100
#define SCANCODE_LEFTCONTROL	29
#define SCANCODE_LEFTALT        56

#define SCANCODE_SPACE		57
#define SCANCODE_LEFTSHIFT	42
#define SCANCODE_RIGHTSHIFT	54
#define SCANCODE_TAB		15
#define SCANCODE_CAPSLOCK	58
#define SCANCODE_BACKSPACE	14

#define SCANCODE_F1             59
#define SCANCODE_F2             60
#define SCANCODE_F3             61
#define SCANCODE_F4             62
#define SCANCODE_F5             63
#define SCANCODE_F6             64
#define SCANCODE_F7             65
#define SCANCODE_F8             66
#define SCANCODE_F9             67
#define SCANCODE_F10            68
#define SCANCODE_F11            87
#define SCANCODE_F12            88

#define SCANCODE_1				 2
#define SCANCODE_2               3
#define SCANCODE_3               4
#define SCANCODE_4               5
#define SCANCODE_5               6
#define SCANCODE_6               7
#define SCANCODE_7               8
#define SCANCODE_8               9
#define SCANCODE_9               10
#define SCANCODE_0               11

#define SCANCODE_DASH			 12
#define SCANCODE_EQUAL			 13

#define SCANCODE_PAGEUP			 104
#define SCANCODE_PAGEDOWN        109
#define SCANCODE_HOME            102
#define SCANCODE_END             107
#define SCANCODE_INSERT          110
#define SCANCODE_DELETE          111

#define SCANCODE_COMMA           51
#define SCANCODE_POINT           52

enum _IOSTATE
{
	IO_IN = 0,
	IO_OUT
};

enum _IOTYPE
{
	IO_CHAR = 0,
	IO_STRING
};

enum _IOREP
{
	IO_REP = 1,
	IO_OTHER
};

typedef struct _IO_PORT_INFO
{
	USHORT Size;
	USHORT Port;
	ULONG State;
	ULONG Type;
	ULONG Rep;

}IO_PORT_INFO, *PIO_PORT_INFO;

typedef struct _KEYBOARD_STATUS{
	BOOLEAN lshift;
	BOOLEAN rshift;
	BOOLEAN lctrl;
	BOOLEAN lalt;
} KEYBOARD_STATUS;


NTSTATUS 
DescIoExitQualification(
		IN ULONG ExitQualification,
		OUT PIO_PORT_INFO PortInfo
);

NTSTATUS
i8042ReadKeyboardData(
		UCHAR* pChar, 
		PBOOLEAN bMouse
);

BOOLEAN 
i8042WriteKeyboardData(
		USHORT Port, 
		UCHAR Data
);

NTSTATUS
KeyboardReadKeystroke(
		PUCHAR pChar, 
		BOOLEAN UnGet, 
		PBOOLEAN bMouse
);

VOID 
HandleIoAccess(
     PCPU_VM_CONTEXT pCPU,
	 PSAVED_REGISTOR pSavedReg
);

VOID 
InitScanCodeMap(
);

UCHAR 
KeyboardScancodeToKeycode(
	UCHAR Char
);

VOID
SetHandleIOAccess(
    BOOLEAN IsSet
);

#endif